﻿using System;
using System.IO;

namespace DZParallelLib.Test.Lib
{
    public static class UtilsForTest
    {
        /// <summary>
        /// Create a duplicate filename - for mocking generating lots of these files.
        /// </summary>
        /// <param name="protoFile"></param>
        /// <param name="newFName"></param>
        /// <returns></returns>
        public static FileInfo GenerateNewDZFile(this FileInfo protoFile, string newFName, DirectoryInfo destDir = null)
        {
            //
            // Before we do any work, make sure everythign is cleaned up... In particular,
            // if some file is sitting on the IDispose queue.
            //

            GC.Collect();
            GC.WaitForPendingFinalizers();

            //
            // Deal with default argument
            //

            if (destDir == null)
                destDir = protoFile.Directory;

            //
            // Copy over.
            //

            var result = new FileInfo(Path.Combine(destDir.FullName, newFName));
            if (result.Exists)
                result.Delete();
            protoFile.CopyTo(result.FullName);
            result.Refresh();

            // Now, try to copy over the complete directory of sub-files!

            var subImageDirectory = new DirectoryInfo(Path.Combine(protoFile.Directory.FullName, string.Format("{0}_files", Path.GetFileNameWithoutExtension(protoFile.Name))));
            if (!subImageDirectory.Exists)
                throw new InvalidOperationException(string.Format("Unable to find the sub image directory {0}!", subImageDirectory.FullName));

            var resultSubImageDirectory = new DirectoryInfo(Path.Combine(result.Directory.FullName, string.Format("{0}_files", Path.GetFileNameWithoutExtension(result.Name))));
            if (resultSubImageDirectory.Exists)
                resultSubImageDirectory.Delete(true);

            CopyFolder(subImageDirectory.FullName, resultSubImageDirectory.FullName);

            return result;
        }

        /// <summary>
        /// Deep copy a folder.
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="destFolder"></param>
        private static void CopyFolder(string folder, string destFolder)
        {
            Directory.CreateDirectory(destFolder);

            foreach (string file in Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories))
            {
                string fileName = Path.GetFileName(file);
                string filePath = Path.GetDirectoryName(file.Substring(folder.Length + (folder.EndsWith("\\") ? 0 : 1)));
                string destFilePath;

                if (!string.IsNullOrEmpty(filePath))
                {
                    string destFolderPath = Path.Combine(destFolder, filePath);

                    Directory.CreateDirectory(destFolderPath);

                    destFilePath = Path.Combine(destFolderPath, fileName);
                }
                else
                {
                    destFilePath = Path.Combine(destFolder, fileName);
                }

                File.Copy(file, destFilePath);
            }
        }
    }
}
